﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetworkLib.Utilities;
using PBO.Network;
using PBO.Network.Enumerations;

namespace PokemonBattle.BattleRoom.Server
{
    public static class RoomServerHelper
    {

        public static ByteArray AcceptChallenge(int from)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_AcceptChallenge_Hash);
            byteArray.WriteInt(from);

            return byteArray;
        }

        public static ByteArray RefuseChallenge(int from)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_RefuseChallenge_Hash);
            byteArray.WriteInt(from);

            return byteArray;
        }

        public static ByteArray Challenge(int from, ChallengeInfo info)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_Challenge_Hash);
            byteArray.WriteInt(from);

            info.Write(byteArray);

            return byteArray;
        }

        public static ByteArray CancelChallenge(int from)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_CancelChallenge_Hash);
            byteArray.WriteInt(from);

            return byteArray;
        }

        public static ByteArray DirectBattle(int server, BattleMode battleMode)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_DirectBattle_Hash);
            byteArray.WriteInt(server);
            byteArray.WriteInt((int)battleMode);

            return byteArray;
        }

        public static ByteArray AgentBattle(int identity, byte playerPosition, BattleMode battleMode)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_AgentBattle_Hash);
            byteArray.WriteInt(identity);

            byteArray.WriteByte(playerPosition);
            byteArray.WriteInt((int)battleMode);

            return byteArray;
        }

        public static ByteArray ReceiveObserveInfo(ObserveInfo info)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_ReceiveObserveInfo_Hash);
            info.Write(byteArray);

            return byteArray;
        }

        public static ByteArray ReceiveBroadcastMessage(string message)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_ReceiveBroadcastMessage_Hash);
            byteArray.WriteUTF(message);

            return byteArray;
        }

        public static ByteArray ReceiveChatMessage(int from, string message)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_ReceiveChatMessage_Hash);
            byteArray.WriteInt(from);

            byteArray.WriteUTF(message);

            return byteArray;
        }

        public static ByteArray LogonSuccess(User info)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_LogonSuccess_Hash);
            info.Write(byteArray);

            return byteArray;
        }

        public static ByteArray LogonFail(string message)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_LogonFail_Hash);
            byteArray.WriteUTF(message);

            return byteArray;
        }

        public static ByteArray BeKicked()
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_BeKicked_Hash);

            return byteArray;
        }

        public static ByteArray UpdateUser(User userInfo)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_UpdateUser_Hash);
            userInfo.Write(byteArray);

            return byteArray;
        }

        public static ByteArray AddNewUser(User userInfo)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_AddNewUser_Hash);
            userInfo.Write(byteArray);

            return byteArray;
        }

        public static ByteArray RemoveUser(int identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_RemoveUser_Hash);
            byteArray.WriteInt(identity);

            return byteArray;
        }

        public static ByteArray AddUserList(IEnumerable<User> users)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_AddUserList_Hash);

            var data = new DataByteArrayList<User>(users.ToArray());
            data.Write(byteArray);

            return byteArray;
        }

        public static ByteArray UpdateRoomSetting(RoomBattleSetting setting)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_UpdateRoomSetting_Hash);
            setting.Write(byteArray);

            return byteArray;
        }

        public static ByteArray RegistFourPlayerSuccess(int identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_RegistFourPlayerSuccess_Hash);
            byteArray.WriteInt(identity);

            return byteArray;
        }

        public static ByteArray AddFourPlayerRoomList(IEnumerable<FourPlayerRoom> rooms)
        {
            var byteArray = new ByteArray();
            byteArray.WriteInt(EnumRoomMethods.Client_AddFourPlayerRoomList_Hash);

            var data = new DataByteArrayList<FourPlayerRoom>(rooms.ToArray());
            data.Write(byteArray);

            return byteArray;
        }

        public static ByteArray AddFourPlayerRoom(int identity, string host)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_AddFourPlayerRoom_Hash);
            byteArray.WriteInt(identity);

            byteArray.WriteUTF(host);

            return byteArray;
        }

        public static ByteArray RemoveFourPlayerRoom(int identity)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_RemoveFourPlayerRoom_Hash);
            byteArray.WriteInt(identity);

            return byteArray;
        }

        public static ByteArray UpdateFourPlayerRoom(int identity, byte userCount)
        {
            ByteArray byteArray = new ByteArray();

            byteArray.WriteInt(EnumRoomMethods.Client_UpdateFourPlayerRoom_Hash);
            byteArray.WriteInt(identity);

            byteArray.WriteByte(userCount);

            return byteArray;
        }


        public static bool InterpretMessage(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            byteArray.BypassHeader();
            int methodID = byteArray.ReadInt();

            switch (methodID)
            {

                case EnumRoomMethods.Server_AcceptChallenge_Hash:
                    return OnAcceptChallenge(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_RefuseChallenge_Hash:
                    return OnRefuseChallenge(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_Challenge_Hash:
                    return OnChallenge(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_CancelChallenge_Hash:
                    return OnCancelChallenge(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_StartBattle_Hash:
                    return OnStartBattle(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_StartFourPlayerBattle_Hash:
                    return OnStartFourPlayerBattle(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_GetObserveInfo_Hash:
                    return OnGetObserveInfo(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_UserLogon_Hash:
                    return OnUserLogon(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_UserLogout_Hash:
                    return OnUserLogout(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_UpdateUser_Hash:
                    return OnUpdateUser(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_ReceiveBroadcastMessage_Hash:
                    return OnReceiveBroadcastMessage(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_ReceiveChatMessage_Hash:
                    return OnReceiveChatMessage(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_ReceiveRoomCommand_Hash:
                    return OnReceiveRoomCommand(sessionID, byteArray, serverService);

                case EnumRoomMethods.Server_RegistFourPlayer_Hash:
                    return OnRegistFourPlayer(sessionID, byteArray, serverService);

            }

            byteArray.Rewind();
            return false;
        }

        private static bool OnAcceptChallenge(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int targetIdentity = byteArray.ReadInt();

            serverService.OnAcceptChallenge(sessionID, targetIdentity);
            return true;
        }

        private static bool OnRefuseChallenge(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int targetIdentity = byteArray.ReadInt();

            serverService.OnRefuseChallenge(sessionID, targetIdentity);
            return true;
        }

        private static bool OnChallenge(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int targetIdentity = byteArray.ReadInt();
            ChallengeInfo info = new ChallengeInfo();
            info.Read(byteArray);

            serverService.OnChallenge(sessionID, targetIdentity, info);
            return true;
        }

        private static bool OnCancelChallenge(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int targetIdentity = byteArray.ReadInt();

            serverService.OnCancelChallenge(sessionID, targetIdentity);
            return true;
        }

        private static bool OnStartBattle(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int with = byteArray.ReadInt();
            ChallengeInfo info = new ChallengeInfo();
            info.Read(byteArray);

            serverService.OnStartBattle(sessionID, with, info);
            return true;
        }

        private static bool OnStartFourPlayerBattle(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int battleIdentity = byteArray.ReadInt();
            byte position = byteArray.ReadByte();

            serverService.OnStartFourPlayerBattle(sessionID, battleIdentity, position);
            return true;
        }

        private static bool OnGetObserveInfo(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int identity = byteArray.ReadInt();

            serverService.OnGetObserveInfo(sessionID, identity);
            return true;
        }

        private static bool OnUserLogon(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            User info = new User();
            info.Read(byteArray);

            serverService.OnUserLogon(sessionID, info);
            return true;
        }

        private static bool OnUserLogout(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {

            serverService.OnUserLogout(sessionID);
            return true;
        }

        private static bool OnUpdateUser(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            User info = new User();
            info.Read(byteArray);

            serverService.OnUpdateUser(sessionID, info);
            return true;
        }

        private static bool OnReceiveBroadcastMessage(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            string message = byteArray.ReadUTF();

            serverService.OnReceiveBroadcastMessage(sessionID, message);
            return true;
        }

        private static bool OnReceiveChatMessage(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            int to = byteArray.ReadInt();
            string message = byteArray.ReadUTF();

            serverService.OnReceiveChatMessage(sessionID, to, message);
            return true;
        }

        private static bool OnReceiveRoomCommand(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {
            string message = byteArray.ReadUTF();

            serverService.OnReceiveRoomCommand(sessionID, message);
            return true;
        }

        private static bool OnRegistFourPlayer(int sessionID, ByteArray byteArray, IRoomServerService serverService)
        {

            serverService.OnRegistFourPlayer(sessionID);
            return true;
        }

    }
}
